home *** CD-ROM | disk | FTP | other *** search
- /* $Id: bitmap.c,v 3.10 1998/07/30 02:39:18 brianp Exp $ */
-
- /*
- * Mesa 3-D graphics library
- * Version: 3.0
- * Copyright (C) 1995-1998 Brian Paul
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-
- /*
- * $Log: bitmap.c,v $
- * Revision 3.10 1998/07/30 02:39:18 brianp
- * feedback/selection modes didn't work
- *
- * Revision 3.9 1998/07/29 04:07:53 brianp
- * feedback was returning wrong values
- *
- * Revision 3.8 1998/05/04 23:54:35 brianp
- * include stdio.h since assert.h needs it on some systems
- *
- * Revision 3.7 1998/03/27 03:30:36 brianp
- * fixed G++ warnings
- *
- * Revision 3.6 1998/03/25 01:24:11 brianp
- * glBitmap in feedback mode returned X,Y offset by bitmap origin (wrong)
- *
- * Revision 3.5 1998/03/05 03:07:56 brianp
- * check for invalid raster pos in gl_direct_bitamp()
- *
- * Revision 3.4 1998/02/27 00:54:29 brianp
- * NULL bitmap image caused assertion- fixed
- *
- * Revision 3.3 1998/02/15 01:32:59 brianp
- * updated driver bitmap function
- *
- * Revision 3.2 1998/02/08 20:23:49 brianp
- * lots of bitmap rendering changes
- *
- * Revision 3.1 1998/02/04 00:33:45 brianp
- * fixed a few cast problems for Amiga StormC compiler
- *
- * Revision 3.0 1998/01/31 20:47:29 brianp
- * initial rev
- *
- */
-
-
- #ifdef PC_HEADER
- #include "all.h"
- #else
- #include <assert.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include "bitmap.h"
- #include "context.h"
- #include "feedback.h"
- #include "image.h"
- #include "macros.h"
- #include "pb.h"
- #include "pixel.h"
- #include "types.h"
- #endif
-
-
-
- /*
- * Render bitmap data.
- */
- static void render_bitmap( GLcontext *ctx, GLint px, GLint py,
- GLsizei width, GLsizei height,
- const struct gl_pixelstore_attrib *unpack,
- const GLubyte *bitmap )
- {
- struct pixel_buffer *PB = ctx->PB;
- GLint row, col;
- GLint pz;
-
- if (!bitmap)
- return;
-
- if (ctx->NewState) {
- gl_update_state(ctx);
- PB_INIT( PB, GL_BITMAP );
- }
-
- if (ctx->Visual->RGBAflag) {
- GLint r, g, b, a;
- r = (GLint) (ctx->Current.RasterColor[0] * 255.0F);
- g = (GLint) (ctx->Current.RasterColor[1] * 255.0F);
- b = (GLint) (ctx->Current.RasterColor[2] * 255.0F);
- a = (GLint) (ctx->Current.RasterColor[3] * 255.0F);
- PB_SET_COLOR( ctx, PB, r, g, b, a );
- }
- else {
- PB_SET_INDEX( ctx, PB, ctx->Current.RasterIndex );
- }
-
- pz = (GLint) ( ctx->Current.RasterPos[2] * DEPTH_SCALE );
-
- for (row=0; row<height; row++) {
- GLubyte *src = (GLubyte *) gl_pixel_addr_in_image( unpack, bitmap,
- width, height, GL_COLOR_INDEX, GL_BITMAP, 0, row, 0 );
-
- if (unpack->LsbFirst) {
- /* Lsb first */
- GLubyte bitmask = 1;
- for (col=0; col<width; col++) {
- if (*src & bitmask) {
- PB_WRITE_PIXEL( PB, px+col, py+row, pz );
- }
- bitmask = bitmask << 1;
- if (bitmask==0) {
- src++;
- bitmask = 1;
- }
- }
-
- PB_CHECK_FLUSH( ctx, PB )
-
- /* get ready for next row */
- if (bitmask!=1)
- src++;
- }
- else {
- /* Msb first */
- GLubyte bitmask = 128;
- for (col=0; col<width; col++) {
- if (*src & bitmask) {
- PB_WRITE_PIXEL( PB, px+col, py+row, pz );
- }
- bitmask = bitmask >> 1;
- if (bitmask==0) {
- src++;
- bitmask = 128;
- }
- }
-
- PB_CHECK_FLUSH( ctx, PB )
-
- /* get ready for next row */
- if (bitmask!=128)
- src++;
- }
- }
-
- gl_flush_pb(ctx);
- }
-
-
-
-
- /*
- * Optimized glBitmap
- */
- GLboolean gl_direct_bitmap( GLcontext *ctx,
- GLsizei width, GLsizei height,
- GLfloat xorig, GLfloat yorig,
- GLfloat xmove, GLfloat ymove,
- const GLubyte *bitmap )
- {
- GLint px = (GLint) ( (ctx->Current.RasterPos[0] - xorig) + 0.0F );
- GLint py = (GLint) ( (ctx->Current.RasterPos[1] - yorig) + 0.0F );
- GLboolean completed = GL_FALSE;
-
- if (ctx->Current.RasterPosValid==GL_FALSE) {
- return GL_TRUE; /* command completed as a no-op */
- }
-
- if (ctx->RenderMode != GL_RENDER)
- return GL_FALSE;
-
- if (ctx->Driver.Bitmap) {
- /* let device driver try to render the bitmap */
- completed = (*ctx->Driver.Bitmap)( ctx, px, py, width, height,
- &ctx->Unpack, bitmap );
- }
- if (!completed) {
- /* We can handle an pixel unpacking combo! */
- render_bitmap( ctx, px, py, width, height, &ctx->Unpack, bitmap );
- }
-
- /* update raster position */
- ctx->Current.RasterPos[0] += xmove;
- ctx->Current.RasterPos[1] += ymove;
-
- return GL_TRUE;
- }
-
-
-
-
- /* Simple unpacking parameters: */
- static struct gl_pixelstore_attrib NoUnpack = {
- 1, /* Alignment */
- 0, /* RowLength */
- 0, /* SkipPixels */
- 0, /* SkipRows */
- 0, /* ImageHeight */
- 0, /* SkipImages */
- GL_FALSE, /* SwapBytes */
- GL_FALSE /* LsbFirst */
- };
-
-
-
- /*
- * Execute a glBitmap command:
- * 1. check for errors
- * 2. feedback/render/select
- * 3. advance raster position
- */
- void gl_Bitmap( GLcontext* ctx,
- GLsizei width, GLsizei height,
- GLfloat xorig, GLfloat yorig,
- GLfloat xmove, GLfloat ymove,
- struct gl_image *bitmap )
- {
- if (width<0 || height<0) {
- gl_error( ctx, GL_INVALID_VALUE, "glBitmap" );
- return;
- }
- if (INSIDE_BEGIN_END(ctx)) {
- gl_error( ctx, GL_INVALID_OPERATION, "glBitmap" );
- return;
- }
- if (ctx->Current.RasterPosValid==GL_FALSE) {
- /* do nothing */
- return;
- }
-
- assert(bitmap->Type == GL_BITMAP);
- assert(bitmap->Format == GL_COLOR_INDEX);
-
- if (ctx->RenderMode==GL_RENDER) {
- GLint px = (GLint) ( (ctx->Current.RasterPos[0] - xorig) + 0.0F );
- GLint py = (GLint) ( (ctx->Current.RasterPos[1] - yorig) + 0.0F );
- GLboolean completed = GL_FALSE;
- if (ctx->Driver.Bitmap) {
- /* let device driver try to render the bitmap */
- completed = (*ctx->Driver.Bitmap)( ctx, px, py, width, height,
- &NoUnpack,
- (const GLubyte *) bitmap->Data );
- }
- if (!completed) {
- /* use generic function */
- render_bitmap( ctx, px, py, width, height, &NoUnpack,
- (const GLubyte *) bitmap->Data );
- }
- }
- else if (ctx->RenderMode==GL_FEEDBACK) {
- GLfloat color[4], texcoord[4], invq;
- color[0] = ctx->Current.RasterColor[0];
- color[1] = ctx->Current.RasterColor[1];
- color[2] = ctx->Current.RasterColor[2];
- color[3] = ctx->Current.RasterColor[3];
- if (ctx->Current.TexCoord[3] == 0.0)
- invq = 1.0F;
- else
- invq = 1.0F / ctx->Current.RasterTexCoord[3];
- texcoord[0] = ctx->Current.RasterTexCoord[0] * invq;
- texcoord[1] = ctx->Current.RasterTexCoord[1] * invq;
- texcoord[2] = ctx->Current.RasterTexCoord[2] * invq;
- texcoord[3] = ctx->Current.RasterTexCoord[3];
- FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_BITMAP_TOKEN );
- gl_feedback_vertex( ctx,
- ctx->Current.RasterPos[0],
- ctx->Current.RasterPos[1],
- ctx->Current.RasterPos[2],
- ctx->Current.RasterPos[3],
- color, ctx->Current.RasterIndex, texcoord );
- }
- else if (ctx->RenderMode==GL_SELECT) {
- /* Bitmaps don't generate selection hits. See appendix B of 1.1 spec. */
- }
-
- /* update raster position */
- ctx->Current.RasterPos[0] += xmove;
- ctx->Current.RasterPos[1] += ymove;
- }
-